home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 3
/
Aminet 3 - July 1994.iso
/
Aminet
/
dev
/
m2
/
Modules.lha
/
Modules
/
Simple3D
/
Simple3D.mod
/
Simple3D.mod
Encoding:
Amiga (detected)
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Modula Implementation
|
1993-12-22
|
29.0 KB
|
1,157 lines
IMPLEMENTATION MODULE Simple3D;
(* Die Erklärung der Funktionen und Hinweise befinden sich im Definitionsfile *)
(* Compiler : M2Amiga 4.097d © 1991 by Andre Wiethoff *)
(*$ StackChk:=FALSE *)
(*$ RangeChk:=FALSE *)
(*$ OverflowChk:=FALSE *)
(*$ NilChk:=FALSE *)
(*$ CaseChk:=FALSE *)
(*$ ReturnChk:=FALSE *)
(*$ Volatile:=FALSE *)
(*$ StackParms:=FALSE *)
(*$ LargeVars:=FALSE *)
FROM SYSTEM IMPORT FFP,ASSEMBLE,ADR,ADDRESS;
FROM GraphicsL IMPORT Draw,Move,SetAPen,InitArea,AreaMove,AreaDraw,
InitTmpRas,AllocRaster,FreeRaster,AreaEnd;
FROM GraphicsD IMPORT RastPortPtr,AreaInfo,RastPort,
AreaInfoPtr,TmpRas,TmpRasPtr,RastPortFlags;
FROM RememberHeap IMPORT NewAllocRemember,NewFreeRemember,NewRememberPtr,
CutRememberStructure,GetAddress;
FROM IntuitionL IMPORT AllocRemember,FreeRemember;
FROM IntuitionD IMPORT RememberPtr;
FROM ExecD IMPORT MemReqSet,MemReqs;
FROM Heap IMPORT AllocMem,Deallocate,Available;
FROM MathTrans IMPORT Atan,Sqrt;
FROM MathFFP IMPORT Cmp;
IMPORT GraphicsL;
IMPORT MathFFP;
(*$ EntryExitCode:=FALSE *)
PROCEDURE SinusTable; (* FFP *)
BEGIN
ASSEMBLE(
DC.L $00000000,$8EF85A3B,$8EF2D53C,$D65E573C,$8EDC6F3D
DC.L $B27EB13D,$D613073D,$F996AC3D,$8E836D3E,$A030573E
DC.L $B1D0D43E,$C363733E,$D4E6CC3E,$E659943E,$F7BA663E
DC.L $8483EB3F,$8D20553F,$95B1BF3F,$9E377C3F,$A6B0DC3F
DC.L $AF1D433F,$B77C023F,$BFCC723F,$C80DE63F,$D03FC83F
DC.L $D8616C3F,$E0722D3F,$E871723F,$F05E963F,$F838FB3F
DC.L $FFFFFE3F,$83D98940,$87A8CB40,$8B6D7840,$8F274340
DC.L $92D5E740,$96791840,$9A108D40,$9D9BFF40,$A11B2340
DC.L $A48DBC40,$A7F37B40,$AB4C2440,$AE977240,$B1D52340
DC.L $B504F240,$B826A740,$BB3A0040,$BE3EBE40,$C134A540
DC.L $C41B7D40,$C6F30940,$C9BB1240,$CC736140,$CF1BBE40
DC.L $D1B3F240,$D43BCE40,$D6B31D40,$D919AE40,$DB6F5240
DC.L $DDB3D740,$DFE71340,$E208DB40,$E4190140,$E6175F40
DC.L $E803C940,$E9DE1D40,$EBA63440,$ED5BEC40,$EEFF2140
DC.L $F08FB140,$F20D8140,$F3787140,$F4D06440,$F6154040
DC.L $F746EA40,$F8654D40,$F9705240,$FA67E240,$FB4BEC40
DC.L $FC1C5D40,$FCD92540,$FD823540,$FE178240,$FE98FD40
DC.L $FF069E40,$FF605C40,$FFA63040,$FFD81440,$FFF60540
DC.L $80000041,$FFF60540,$FFD81440,$FFA63040,$FF605C40
DC.L $FF069E40,$FE98FD40,$FE178240,$FD823640,$FCD92540
DC.L $FC1C5D40,$FB4BED40,$FA67E240,$F9705240,$F8654E40
DC.L $F746EB40,$F6154040,$F4D06440,$F3787140,$F20D8240
DC.L $F08FB340,$EEFF2240,$ED5BED40,$EBA63640,$E9DE1E40
DC.L $E803CC40,$E6175F40,$E4190240,$E208DB40,$DFE71640
DC.L $DDB3D940,$DB6F5240,$D919B040,$D6B32040,$D43BD040
DC.L $D1B3F640,$CF1BBD40,$CC736340,$C9BB1240,$C6F30B40
DC.L $C41B7F40,$C134A740,$BE3EBE40,$BB3A0040,$B826AA40
DC.L $B504F540,$B1D52340,$AE977540,$AB4C2440,$A7F37E40
DC.L $A48DBF40,$A11B2640,$9D9C0240,$9A108D40,$96791C40
DC.L $92D5E740,$8F274640,$8B6D7B40,$87A8CB40,$83D98C40
DC.L $80000640,$F838FA3F,$F05E963F,$E871713F,$E072353F
DC.L $D8616C3F,$D03FD03F,$C80DF53F,$BFCC723F,$B77C023F
DC.L $AF1D423F,$A6B0E43F,$9E377C3F,$95B1C73F,$8D20553F
DC.L $8483EC3F,$F7BA663E,$E659A43E,$D4E6DB3E,$C363733E
DC.L $B1D0D43E,$A030573E,$8E837C3E,$F996AC3D,$D613273D
DC.L $B27ED13D,$8EDC6F3D,$D65E5B3C,$8EF2D73C,$8EF8D83B
DC.L $00000000,$8EF7D9BB,$8EF296BC,$D65E1BBC,$8EDC6FBD
DC.L $B27EB1BD,$D612E8BD,$F9968CBD,$8E835DBE,$A03057BE
DC.L $B1D0C4BE,$C36373BE,$D4E6DBBE,$E65984BE,$F7BA47BE
DC.L $8483ECBF,$8D2055BF,$95B1B8BF,$9E377CBF,$A6B0D5BF
DC.L $AF1D3BBF,$B77BFABF,$BFCC6BBF,$C80DE7BF,$D03FC8BF
DC.L $D8616CBF,$E07226BF,$E8716BBF,$F05E8FBF,$F838F3BF
DC.L $FFFFFEBF,$83D989C0,$87A8CBC0,$8B6D71C0,$8F2743C0
DC.L $92D5E4C0,$967918C0,$9A108DC0,$9D9BFCC0,$A11B20C0
DC.L $A48DB6C0,$A7F37BC0,$AB4C21C0,$AE9772C0,$B1D520C0
DC.L $B504F2C0,$B826A4C0,$BB39FDC0,$BE3EBCC0,$C134A5C0
DC.L $C41B7AC0,$C6F30BC0,$C9BB12C0,$CC7361C0,$CF1BBBC0
DC.L $D1B3EFC0,$D43BD0C0,$D6B31EC0,$D919ACC0,$DB6F50C0
DC.L $DDB3D5C0,$DFE710C0,$E208DBC0,$E41900C0,$E6175DC0
DC.L $E803CAC0,$E9DE1BC0,$EBA634C0,$ED5BECC0,$EEFF20C0
DC.L $F08FB0C0,$F20D82C0,$F37871C0,$F4D063C0,$F6153EC0
DC.L $F746E9C0,$F8654DC0,$F97052C0,$FA67E2C0,$FB4BEDC0
DC.L $FC1C5CC0,$FCD924C0,$FD8236C0,$FE1781C0,$FE98FDC0
DC.L $FF069EC0,$FF605CC0,$FFA630C0,$FFD814C0,$FFF605C0
DC.L $800000C1,$FFF605C0,$FFD815C0,$FFA630C0,$FF605DC0
DC.L $FF069FC0,$FE98FDC0,$FE1782C0,$FD8237C0,$FCD925C0
DC.L $FC1C5EC0,$FB4BECC0,$FA67E3C0,$F97052C0,$F8654FC0
DC.L $F746EBC0,$F61540C0,$F4D065C0,$F37873C0,$F20D85C0
DC.L $F08FB3C0,$EEFF22C0,$ED5BEDC0,$EBA634C0,$E9DE22C0
DC.L $E803CEC0,$E6175FC0,$E41903C0,$E208DEC0,$DFE713C0
DC.L $DDB3DCC0,$DB6F54C0,$D919B1C0,$D6B322C0,$D43BCEC0
DC.L $D1B3F4C0,$CF1BC0C0,$CC7363C0,$C9BB17C0,$C6F310C0
DC.L $C41B7FC0,$C134A7C0,$BE3EC1C0,$BB3A00C0,$B826ACC0
DC.L $B504F5C0,$B1D526C0,$AE9775C0,$AB4C24C0,$A7F37EC0
DC.L $A48DBCC0,$A11B2AC0,$9D9C02C0,$9A1094C0,$967918C0
DC.L $92D5EAC0,$8F2749C0,$8B6D75C0,$87A8CBC0,$83D989C0
DC.L $FFFFF7BF,$F83910BF,$F05E9DBF,$E87180BF,$E07243BF
DC.L $D86173BF,$D03FD7BF,$C80DF5BF,$BFCC72BF,$B77C09BF
DC.L $AF1D4ABF,$A6B0DCBF,$9E377CBF,$95B1BFBF,$8D206DBF
DC.L $848402BF,$F7BA75BE,$E659B3BE,$D4E6EBBE,$C36373BE
DC.L $B1D0E4BE,$A03076BE,$8E835DBE,$F996ACBD,$D61327BD
DC.L $B27ED1BD,$8EDC6FBD,$D65E57BC,$8EF354BC,$8EF9DCBB
END);
END SinusTable;
VAR sinus : POINTER TO ARRAY[0..359] OF FFP;
PROCEDURE Sin(w : LONGINT) : FFP;
BEGIN
RETURN sinus^[w MOD 360];
END Sin;
PROCEDURE Cos(w : LONGINT) : FFP;
BEGIN
RETURN sinus^[(w+90) MOD 360];
END Cos;
VAR rememberObject : NewRememberPtr;
rememberDisplay : NewRememberPtr;
PROCEDURE InitObject() : ObjectHandlePtr;
VAR obj : ObjectHandlePtr;
BEGIN
obj:=NewAllocRemember(rememberObject,SIZE(ObjectHandle),FALSE);
IF obj#NIL THEN
WITH obj^ DO
firstArea:=NIL;
rememberData:=NIL;
rotX:=0; rotY:=0; rotZ:=0;
WITH trans DO
x:=0.0; y:=0.0; z:=0.0;
END;
END;
END;
RETURN obj;
END InitObject;
PROCEDURE AddPoint( object : ObjectHandlePtr;
VAR area : AreaPtr;
x,y,z : FFP);
VAR t : AreaPtr;
c : INTEGER;
BEGIN
IF object#NIL THEN
IF area=NIL THEN
area:=AllocRemember(object^.rememberData,SIZE(Area),
MemReqSet{memClear});
t:=area;
ELSE
t:=area; c:=1;
WHILE t^.nextPoint#NIL DO t:=t^.nextPoint; INC(c); END;
IF c<255 THEN
t^.nextPoint:=AllocRemember(object^.rememberData,SIZE(Area),
MemReqSet{memClear});
END;
t:=t^.nextPoint;
END;
IF t#NIL THEN
t^.point.x:=x;
t^.point.y:=y;
t^.point.z:=z;
END;
END;
END AddPoint;
PROCEDURE AddArea(object : ObjectHandlePtr;
area : AreaPtr;
lc,ic : INTEGER);
VAR obj,t : ObjectPtr;
BEGIN
IF object#NIL THEN
obj:=object^.firstArea;
IF obj=NIL THEN
obj:=AllocRemember(object^.rememberData,SIZE(Object),
MemReqSet{memClear});
t:=obj;
ELSE
t:=obj;
WHILE t^.nextArea#NIL DO t:=t^.nextArea; END;
t^.nextArea:=AllocRemember(object^.rememberData,SIZE(Object),
MemReqSet{memClear});
t:=t^.nextArea;
END;
IF t#NIL THEN
t^.firstPoint:=area;
t^.lineColor:=lc;
t^.innerColor:=ic;
END;
object^.firstArea:=obj;
END;
END AddArea;
PROCEDURE GetRect(object : ObjectHandlePtr;
x1,y1, x2,y2 : FFP) : AreaPtr;
VAR area : AreaPtr;
BEGIN
area:=NIL;
AddPoint(object,area,x1,y1,0.0);
AddPoint(object,area,x2,y1,0.0);
AddPoint(object,area,x2,y2,0.0);
AddPoint(object,area,x1,y2,0.0);
RETURN area;
END GetRect;
PROCEDURE GetCircle(object : ObjectHandlePtr;
mx,my : FFP;
r : FFP;
num : INTEGER;
deg : INTEGER) : AreaPtr;
VAR area : AreaPtr;
t : INTEGER;
w : LONGINT;
BEGIN
IF deg>360 THEN deg:=360; END;
IF deg>=0 THEN
area:=NIL;
FOR t:=0 TO num DO
w:=(LONGINT(t)*deg)/LONGINT(num);
AddPoint(object,area,mx+r*Sin(w),my+r*Cos(w),0.0);
END;
END;
RETURN area;
END GetCircle;
PROCEDURE CopyArea(object : ObjectHandlePtr;
area : AreaPtr) : AreaPtr;
VAR a,b,t : AreaPtr;
BEGIN
IF object#NIL THEN
a:=NIL;
IF area#NIL THEN
a:=AllocRemember(object^.rememberData,SIZE(Area),MemReqSet{memClear});
IF a#NIL THEN
t:=a;
a^.point:=area^.point; a^.nextPoint:=NIL;
WHILE area^.nextPoint#NIL DO
t^.nextPoint:=AllocRemember(object^.rememberData,SIZE(Area),
MemReqSet{memClear});
area:=area^.nextPoint;
IF t^.nextPoint#NIL THEN
t:=t^.nextPoint;
t^.point:=area^.point;
END;
END;
END;
END;
END;
RETURN a;
END CopyArea;
PROCEDURE RotateArea(area : AreaPtr;
rx,ry,rz : INTEGER);
VAR f11,f12,f13,f21,f22,f23,f31,f32,f33 : FFP;
cx,cy,cz,sx,sy,sz : FFP;
BEGIN
cx:=Cos(rx);
sx:=Sin(rx);
cy:=Cos(ry);
sy:=Sin(ry);
cz:=Cos(rz);
sz:=Sin(rz);
f11:=cy*cz; f12:=cy*sz; f13:=-sy;
f21:=sx*sy*cz-cx*sz; f22:=sx*sy*sz+cx*cz; f23:=sx*cy;
f31:=cx*sy*cz+sx*sz; f32:=cx*sy*sz-sx*cz; f33:=cx*cy;
WHILE area#NIL DO
WITH area^.point DO
x:=x*f11+y*f12+z*f13;
y:=x*f21+y*f22+z*f23;
z:=x*f31+y*f32+z*f33;
END;
area:=area^.nextPoint;
END;
END RotateArea;
PROCEDURE MoveAreaDirect(area : AreaPtr;
tx,ty,tz : FFP);
BEGIN
WHILE area#NIL DO
WITH area^.point DO
x:=x+tx; y:=y+ty; z:=z+tz;
END;
area:=area^.nextPoint;
END;
END MoveAreaDirect;
PROCEDURE GetCube(x1,y1, x2,y2, h : FFP;
lc,ic : INTEGER) : ObjectHandlePtr;
VAR obj : ObjectHandlePtr;
area : AreaPtr;
BEGIN
obj:=InitObject();
IF obj#NIL THEN
area:=GetRect(obj,x1,y1,x2,y2);
AddArea(obj,area,lc,ic);
area:=CopyArea(obj,area);
MoveAreaDirect(area,0.0,0.0,h);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x1,y1,0.0);
AddPoint(obj,area,x1,y1,h);
AddPoint(obj,area,x1,y2,h);
AddPoint(obj,area,x1,y2,0.0);
AddArea(obj,area,lc,ic);
area:=CopyArea(obj,area);
MoveAreaDirect(area,x2-y1,0.0,0.0);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x1,y1,0.0);
AddPoint(obj,area,x1,y1,h);
AddPoint(obj,area,x2,y1,h);
AddPoint(obj,area,x2,y1,0.0);
AddArea(obj,area,lc,ic);
area:=CopyArea(obj,area);
MoveAreaDirect(area,0.0,y2-y1,0.0);
AddArea(obj,area,lc,ic);
END;
RETURN obj;
END GetCube;
PROCEDURE GetPyramid(x1,y1, x2,y2, h : FFP;
lc,ic : INTEGER) : ObjectHandlePtr;
VAR obj : ObjectHandlePtr;
area : AreaPtr;
BEGIN
obj:=InitObject();
IF obj#NIL THEN
area:=GetRect(obj,x1,y1,x2,y2);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x1,y1,0.0);
AddPoint(obj,area,(x1+x2)/2.0,(y1+y2)/2.0,h);
AddPoint(obj,area,x2,y1,0.0);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x2,y1,0.0);
AddPoint(obj,area,(x1+x2)/2.0,(y1+y2)/2.0,h);
AddPoint(obj,area,x2,y2,0.0);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x2,y2,0.0);
AddPoint(obj,area,(x1+x2)/2.0,(y1+y2)/2.0,h);
AddPoint(obj,area,x1,y2,0.0);
AddArea(obj,area,lc,ic);
area:=NIL;
AddPoint(obj,area,x1,y2,0.0);
AddPoint(obj,area,(x1+x2)/2.0,(y1+y2)/2.0,h);
AddPoint(obj,area,x1,y1,0.0);
AddArea(obj,area,lc,ic);
END;
RETURN obj;
END GetPyramid;
PROCEDURE GetRotationObject(area : AreaPtr;
num : INTEGER;
flags : RotationFlagSet;
lc,ic : INTEGER) : ObjectHandlePtr;
VAR a,b,na : AreaPtr;
obj : ObjectHandlePtr;
t : INTEGER;
w : LONGINT;
x1,x2,y1,y2,z1,z2,wi : FFP;
ox1,oz1,ox2,oz2 : FFP;
nx1,nz1,nx2,nz2 : FFP;
fl : BOOLEAN;
BEGIN
fl:=TRUE;
obj:=InitObject();
IF (area#NIL) AND (obj#NIL) THEN
a:=area;
WHILE a#NIL DO
b:=a^.nextPoint;
IF b=NIL THEN
b:=area;
IF notClosed IN flags THEN
fl:=FALSE;
END;
na:=NIL;
IF bottomClosed IN flags THEN
WITH a^.point DO
x1:=x;
y1:=y;
END;
FOR t:=1 TO num DO
w:=(t*360)/num;
wi:=Cos(w);
nx1:=x1*wi;
wi:=Sin(w);
nz1:=x1*wi;
AddPoint(obj,na,nx1,y1,nz1);
END;
AddArea(obj,na,lc,ic);
END;
na:=NIL;
IF topClosed IN flags THEN
WITH b^.point DO
x1:=x;
y1:=y;
END;
FOR t:=1 TO num DO
w:=(t*360)/num;
wi:=Cos(w);
nx1:=x1*wi;
wi:=Sin(w);
nz1:=x1*wi;
AddPoint(obj,na,nx1,y1,nz1);
END;
AddArea(obj,na,lc,ic);
END;
END;
IF fl THEN
WITH a^.point DO
x1:=x; y1:=y;
ox1:=x; oz1:=0.0;
END;
WITH b^.point DO
x2:=x; y2:=y;
ox2:=x; oz2:=0.0;
END;
FOR t:=1 TO num DO
na:=NIL;
w:=(t*360)/num;
wi:=Cos(w);
nx1:=x1*wi;
nx2:=x2*wi;
wi:=Sin(w);
nz1:=x1*wi;
nz2:=x2*wi;
AddPoint(obj,na,ox1,y1,oz1);
AddPoint(obj,na,ox2,y2,oz2);
AddPoint(obj,na,nx2,y2,nz2);
AddPoint(obj,na,nx1,y1,nz1);
AddArea(obj,na,lc,ic);
ox1:=nx1; ox2:=nx2; oz1:=nz1; oz2:=nz2;
END;
END;
a:=a^.nextPoint;
END;
END;
RETURN obj;
END GetRotationObject;
PROCEDURE GetSphere(mx,my,mz : FFP;
r : FFP;
numV,numH : INTEGER;
lc,ic : INTEGER) : ObjectHandlePtr;
VAR area : AreaPtr;
obj1,obj2 : ObjectHandlePtr;
BEGIN
obj1:=InitObject();
IF obj1#NIL THEN
area:=GetCircle(obj1,0.0,0.0,r,numV,180);
IF area#NIL THEN
obj2:=GetRotationObject(area,numH,
RotationFlagSet{notClosed},lc,ic);
FreeRemember(ADR(obj1^.rememberData),TRUE);
CutRememberStructure(rememberObject,obj1,TRUE);
WITH obj2^.trans DO
x:=mx; y:=my; z:=mz;
END;
END;
END;
RETURN obj2;
END GetSphere;
PROCEDURE CopyObject(obj : ObjectHandlePtr) : ObjectHandlePtr;
VAR o : ObjectHandlePtr;
a,b,c : ObjectPtr;
BEGIN
o:=NIL;
IF obj#NIL THEN
o:=NewAllocRemember(rememberObject,SIZE(ObjectHandle),FALSE);
IF o#NIL THEN
o^:=obj^;
WITH o^ DO
firstArea:=NIL;
rememberData:=NIL;
END;
b:=obj^.firstArea;
c:=NIL;
WHILE b#NIL DO
a:=AllocRemember(o^.rememberData,SIZE(Object),MemReqSet{memClear});
IF a#NIL THEN
a^:=b^;
IF b=obj^.firstArea THEN o^.firstArea:=a; END;
a^.firstPoint:=CopyArea(o,b^.firstPoint);
IF c#NIL THEN
c^.nextArea:=a;
END;
c:=a;
END;
b:=b^.nextArea;
END;
END;
END;
RETURN o;
END CopyObject;
PROCEDURE MoveObject(obj : ObjectHandlePtr;
tx,ty,tz : FFP);
BEGIN
IF obj#NIL THEN
WITH obj^.trans DO
x:=x+tx; y:=y+ty; z:=z+tz;
END;
END;
END MoveObject;
PROCEDURE MoveObjectDirect(obj : ObjectHandlePtr;
tx,ty,tz : FFP);
VAR o : ObjectPtr;
BEGIN
IF obj#NIL THEN
o:=obj^.firstArea;
WHILE o#NIL DO
MoveAreaDirect(o^.firstPoint,tx,ty,tz);
o:=o^.nextArea;
END;
END;
END MoveObjectDirect;
PROCEDURE RotateObject(obj : ObjectHandlePtr;
rx,ry,rz : INTEGER);
VAR a : AreaPtr;
BEGIN
IF obj#NIL THEN
WITH obj^ DO
rotX:=rotX+rx; rotY:=rotY+ry; rotZ:=rotZ+rz;
END;
END;
END RotateObject;
PROCEDURE GetObjectPosition(obj : ObjectHandlePtr;
VAR px,py,pz : FFP);
BEGIN
IF obj#NIL THEN
WITH obj^.trans DO
px:=x; py:=y; pz:=z;
END;
END;
END GetObjectPosition;
PROCEDURE GetObjectRotation(obj : ObjectHandlePtr;
VAR rx,ry,rz : INTEGER);
BEGIN
IF obj#NIL THEN
WITH obj^ DO
rx:=rotX; ry:=rotY; rz:=rotZ;
END;
END;
END GetObjectRotation;
PROCEDURE InitDisplay() : DisplayPtr;
VAR dp : DisplayPtr;
BEGIN
dp:=NewAllocRemember(rememberDisplay,SIZE(Display),FALSE);
IF dp#NIL THEN
WITH dp^ DO
firstObject:=NIL;
cameraPos.x:=0.0; cameraPos.y:=0.0; cameraPos.z:=500.0;
viewPos.x:=0.0; viewPos.y:=0.0; viewPos.z:=0.0;
distanceScreen:=200.0;
END;
END;
RETURN dp;
END InitDisplay;
PROCEDURE AddObject(display : DisplayPtr;
object : ObjectHandlePtr);
VAR obj,t : ObjectHandlePtr;
BEGIN
IF (display#NIL) AND (object#NIL) THEN
obj:=display^.firstObject;
object^.nextObject:=NIL;
IF obj=NIL THEN
display^.firstObject:=object;
ELSE
t:=obj;
WHILE t^.nextObject#NIL DO t:=t^.nextObject; END;
t^.nextObject:=object;
END;
END;
END AddObject;
PROCEDURE SetCamera(display : DisplayPtr;
px,py,pz : FFP;
vx,vy,vz : FFP;
dist : FFP);
BEGIN
IF display#NIL THEN
WITH display^.cameraPos DO
x:=px; y:=py; z:=pz;
END;
WITH display^.viewPos DO
x:=vx; y:=vy; z:=vz;
END;
display^.distanceScreen:=dist;
END;
END SetCamera;
TYPE RasterPtr = POINTER TO Raster;
Raster = RECORD
rp : RastPortPtr;
tmpRas : TmpRas;
mem : ADDRESS;
w,h : INTEGER;
former : TmpRasPtr;
END;
VAR rememberRaster : NewRememberPtr;
PROCEDURE OpenTmpRas(rp : RastPortPtr) : RasterPtr;
VAR tr : RasterPtr; (* aus GraphicsSupport, Sorry! *)
hd : ADDRESS;
BEGIN
IF rp#NIL THEN
tr:=NewAllocRemember(rememberRaster,SIZE(Raster),FALSE);
IF tr#NIL THEN
WITH rp^.bitMap^ DO
hd:=AllocRaster(bytesPerRow*8,rows);
IF hd#NIL THEN
tr^.rp:=rp;
tr^.mem:=hd;
tr^.w:=bytesPerRow*8; tr^.h:=rows;
InitTmpRas(tr^.tmpRas,hd,bytesPerRow*rows);
tr^.former:=rp^.tmpRas;
rp^.tmpRas:=ADR(tr^.tmpRas);
ELSE
CutRememberStructure(rememberRaster,tr,TRUE);
tr:=NIL;
END;
END;
END;
END;
RETURN tr;
END OpenTmpRas;
PROCEDURE CloseTmpRas(rast : RasterPtr);
VAR rem : NewRememberPtr;
rr : RasterPtr;
b : BOOLEAN;
BEGIN
IF rast#NIL THEN
WITH rast^ DO
IF mem#NIL THEN
FreeRaster(mem,w,h);
END;
END;
b:=TRUE;
rem:=rememberRaster;
WHILE rem#NIL DO
rr:=GetAddress(rem);
IF rr#rast THEN
IF rr^.former=ADR(rast^.tmpRas) THEN
rr^.former:=rast^.former;
b:=FALSE;
END;
END;
rem:=rem^.next;
END;
IF b THEN
rast^.rp^.tmpRas:=rast^.former;
END;
CutRememberStructure(rememberRaster,rast,TRUE);
rast:=NIL;
END;
END CloseTmpRas;
(*$ EntryExitCode:=FALSE *)
PROCEDURE Swap(i1{0},i2{1} : LONGINT;
adr{10} : ADDRESS);
BEGIN
ASSEMBLE(
LSL.L #2,D0
LSL.L #2,D1
MOVE.L A2,A1
ADD.L D0,A1
ADD.L D1,A2
MOVE.L (A1),D0
MOVE.L (A2),(A1)
MOVE.L D0,(A2)
RTS
END);
END Swap;
(*$ EntryExitCode:=FALSE *)
PROCEDURE QuickSort(left{6},right{7} : LONGINT;
adr{10} : ADDRESS);
BEGIN
ASSEMBLE(
MOVEM.L D2-D7,-(SP)
r1:
MOVE.L D6,D2
MOVE.L D7,D3
MOVE.L D6,D5
ADD.L D7,D5
LSL.L #1,D5
AND.L #$FFFFFFFC,D5
MOVE.L D5,A0
ADD.L A2,A0
MOVE.L (A0),A0
MOVE.L Object.pz(A0),D4
r2:
w1:
MOVE.L A2,A0
MOVE.L D2,D5
LSL.L #2,D5
ADD.L D5,A0
MOVE.L (A0),A0
MOVE.L Object.pz(A0),D1
MOVE.L D4,D0
JSR Cmp(A6)
BLE ausw1
ADDQ.L #1,D2
BRA w1
ausw1:
w2:
MOVE.L A2,A0
MOVE.L D3,D5
LSL.L #2,D5
ADD.L D5,A0
MOVE.L (A0),A0
MOVE.L Object.pz(A0),D0
MOVE.L D4,D1
JSR Cmp(A6)
BLE ausw2
SUBQ.L #1,D3
BRA w2
ausw2:
CMP.L D3,D2
BGT endif
MOVEM.L A1-A2,-(SP)
MOVE.L D2,D0
MOVE.L D3,D1
BSR Swap
MOVEM.L (SP)+,A1-A2
ADDQ.L #1,D2
SUBQ.L #1,D3
endif:
CMP.L D3,D2
BLE r2
MOVE.L D7,D0
MOVE.L D2,D1
CMP.L D2,D7
BLE endif2
MOVEM.L D2-D7,-(SP)
MOVE.L D2,D6
BSR QuickSort
MOVEM.L (SP)+,D2-D7
endif2:
MOVE.L D3,D7
CMP.L D7,D6
BLT r1
MOVEM.L (SP)+,D2-D7
RTS
END);
END QuickSort;
(*$ EntryExitCode:=FALSE *)
PROCEDURE SortPList(as{0} : ADDRESS;
pnum{7} : LONGINT);
BEGIN
ASSEMBLE(
MOVE.L D6,-(SP)
MOVE.L A2,-(SP)
TST.L D0
BEQ ende
MOVE.L MathFFP(A4),A6
MOVE.L D0,A2
MOVEQ #0,D6
SUBQ.L #1,D7
BSR QuickSort
ende:
MOVE.L (SP)+,A2
MOVE.L (SP)+,D6
RTS
END);
END SortPList;
CONST WC = 180.0/3.141592653589;
PROCEDURE SimpleRender(display : DisplayPtr;
rp : RastPortPtr;
flags : RenderFlagSet);
VAR actObjh : ObjectHandlePtr;
actObj : ObjectPtr;
actArea : AreaPtr;
ai : AreaInfo;
mem : ADDRESS;
oai : AreaInfoPtr;
rt : RasterPtr;
alist : POINTER TO ARRAY[0..16383] OF ObjectPtr;
p1,p2,op,actSA : ObjectPtr;
xn,yn,zn,cx,cy,cz,vh,vd,pd,hm,lm : FFP;
f11,f12,f13,f21,f22,f23,f31,f32,f33 : FFP;
sy,sx,sz,tx,ty,tz,zz,gy,px,py,pz : FFP;
xl,yl,xp,yp,num,nz,mx,my,rx,ry : INTEGER;
BEGIN
IF (display#NIL) AND (rp#NIL) THEN
mem:=NIL;
IF rp^.bitMap#NIL THEN
WITH rp^.bitMap^ DO
mx:=4*bytesPerRow;
my:=rows/2;
END;
END;
IF hiresMode IN flags THEN hm:=2.0; ELSE hm:=1.0; END;
IF laceMode IN flags THEN lm:=2.0; ELSE lm:=1.0; END;
WITH display^.cameraPos DO
cx:=x; cy:=y; cz:=z;
END;
WITH display^.viewPos DO
cx:=cx-x; cy:=cy-y; cz:=cz-z;
px:=x; py:=y; pz:=z;
END;
vd:=Sqrt(cx*cx+cy*cy+cz*cz);
IF cz=0.0 THEN
ry:=0;
ELSE
ry:=TRUNC(Atan(cx/cz)*WC);
END;
IF cz<0.0 THEN INC(ry,180); END;
pd:=Sqrt(cz*cz+cx*cx);
IF pd=0.0 THEN
rx:=90;
ELSE
rx:=-TRUNC(Atan(cy/pd)*WC);
END;
vh:=display^.distanceScreen;
IF hiddenLine IN flags THEN
num:=0;
actObjh:=display^.firstObject;
WHILE actObjh#NIL DO
actObj:=actObjh^.firstArea;
WHILE actObj#NIL DO
INC(num);
actObj:=actObj^.nextArea;
END;
actObjh:=actObjh^.nextObject;
END;
AllocMem(alist,SIZE(ObjectPtr)*(num+2),FALSE);
rt:=OpenTmpRas(rp);
IF rt#NIL THEN
AllocMem(mem,258*5,TRUE);
IF mem#NIL THEN
InitArea(ai,mem,256);
oai:=rp^.areaInfo;
rp^.areaInfo:=ADR(ai);
INCL(rp^.flags,areaOutline);
num:=0;
actObjh:=display^.firstObject;
WHILE actObjh#NIL DO
actObj:=actObjh^.firstArea;
WITH actObjh^ DO
cx:=Cos(rotX+rx);
sx:=Sin(rotX+rx);
cy:=Cos(rotY+ry);
sy:=Sin(rotY+ry);
cz:=Cos(rotZ);
sz:=Sin(rotZ);
END;
WITH actObjh^.trans DO
tx:=x; ty:=y; tz:=z;
END;
f11:=cy*cz; f12:=cy*sz; f13:=-sy;
f21:=sx*sy*cz-cx*sz; f22:=sx*sy*sz+cx*cz; f23:=sx*cy;
f31:=cx*sy*cz+sx*sz; f32:=cx*sy*sz-sx*cz; f33:=cx*cy;
WHILE actObj#NIL DO
alist^[num]:=actObj;
IF alist^[num]#NIL THEN
zz:=0.0; nz:=0;
p1:=NIL; p2:=NIL; op:=NIL;
actArea:=actObj^.firstPoint;
WHILE actArea#NIL DO
WITH actArea^.point DO
xn:=x*f11+y*f12+z*f13+tx-px;
yn:=x*f21+y*f22+z*f23+ty-py;
zn:=x*f31+y*f32+z*f33+tz-pz;
END;
WITH actArea^ DO
x:=TRUNC((xn*vh*hm)/(vd-zn));
y:=TRUNC((yn*vh*lm)/(vd-zn));
zz:=zz+zn; INC(nz);
actArea:=actArea^.nextPoint;
END;
END;
IF nz>0 THEN
alist^[num]^.pz:=zz/FFP(nz);
ELSE
alist^[num]^.pz:=0.0;
END;
INC(num);
END;
actObj:=actObj^.nextArea;
END;
actObjh:=actObjh^.nextObject;
END;
SortPList(alist,num);
ASSEMBLE(
MOVEM.L D2-D4/A2-A3,-(SP)
MOVE.L GraphicsL(A4),A6
MOVE.L alist(A5),A3
for:
MOVE.L (A3),A2
CMP.L #0,A2
BEQ endfor
MOVE.L rp(A5),A1
MOVE.W Object.lineColor(A2),D0
MOVE.B D0,RastPort.aOlPen(A1)
MOVEQ #0,D0
MOVE.W Object.innerColor(A2),D0
JSR SetAPen(A6)
MOVE.L Object.firstPoint(A2),A2
CMP.L #0,A2
BEQ endif
MOVE.W Area.x(A2),D0
ADD.W mx(A5),D0
MOVE.W my(A5),D1
SUB.W Area.y(A2),D1
MOVE.L rp(A5),A1
JSR AreaMove(A6)
MOVE.L Area.nextPoint(A2),A2
endif:
w1:
CMP.L #0,A2
BEQ wende1
MOVE.W Area.x(A2),D0
ADD.W mx(A5),D0
MOVE.W my(A5),D1
SUB.W Area.y(A2),D1
MOVE.L rp(A5),A1
JSR AreaDraw(A6)
MOVE.L Area.nextPoint(A2),A2
BRA w1
wende1:
MOVE.L rp(A5),A1
JSR AreaEnd(A6)
ADDQ.L #4,A3
BRA for
endfor:
MOVEM.L (SP)+,D2-D4/A2-A3
END);
Deallocate(mem);
END;
CloseTmpRas(rt);
END;
Deallocate(alist);
ELSE
actObjh:=display^.firstObject;
WHILE actObjh#NIL DO
actObj:=actObjh^.firstArea;
WITH actObjh^ DO
cx:=Cos(rotX+rx);
sx:=Sin(rotX+rx);
cy:=Cos(rotY+ry);
sy:=Sin(rotY+ry);
cz:=Cos(rotZ);
sz:=Sin(rotZ);
END;
WITH actObjh^.trans DO
tx:=x; ty:=y; tz:=z;
END;
f11:=cy*cz; f12:=cy*sz; f13:=-sy;
f21:=sx*sy*cz-cx*sz; f22:=sx*sy*sz+cx*cz; f23:=sx*cy;
f31:=cx*sy*cz+sx*sz; f32:=cx*sy*sz-sx*cz; f33:=cx*cy;
WHILE actObj#NIL DO
SetAPen(rp,actObj^.lineColor);
actArea:=actObj^.firstPoint;
IF actArea#NIL THEN
WITH actArea^.point DO
xn:=x*f11+y*f12+z*f13+tx-px;
yn:=x*f21+y*f22+z*f23+ty-py;
zn:=x*f31+y*f32+z*f33+tz-pz;
END;
xp:=TRUNC((xn*vh*hm)/(vd-zn));
yp:=TRUNC((yn*vh*lm)/(vd-zn));
Move(rp,xp+mx,my-yp);
END;
WHILE actArea#NIL DO
WITH actArea^.point DO
xn:=x*f11+y*f12+z*f13+tx-px;
yn:=x*f21+y*f22+z*f23+ty-py;
zn:=x*f31+y*f32+z*f33+tz-pz;
END;
xl:=TRUNC((xn*vh*hm)/(vd-zn));
yl:=TRUNC((yn*vh*lm)/(vd-zn));
Draw(rp,xl+mx,my-yl);
actArea:=actArea^.nextPoint;
END;
Draw(rp,xp+mx,my-yp);
actObj:=actObj^.nextArea;
END;
actObjh:=actObjh^.nextObject;
END;
END;
END;
END SimpleRender;
PROCEDURE FreeObject( display : DisplayPtr;
VAR object : ObjectHandlePtr);
VAR t,o : ObjectHandlePtr;
BEGIN
IF object#NIL THEN
IF object^.rememberData#NIL THEN
FreeRemember(ADR(object^.rememberData),TRUE);
END;
o:=NIL;
IF display#NIL THEN
IF display^.firstObject=object THEN
display^.firstObject:=object^.nextObject;
ELSE
t:=display^.firstObject;
WHILE t#NIL DO
IF t=object THEN
IF o#NIL THEN
o^.nextObject:=t^.nextObject;
END;
END;
o:=t;
t:=t^.nextObject;
END;
END;
END;
CutRememberStructure(rememberObject,object,TRUE);
END;
object:=NIL;
END FreeObject;
PROCEDURE FreeDisplay(VAR display : DisplayPtr);
VAR t,d : ObjectHandlePtr;
BEGIN
IF display#NIL THEN
t:=display^.firstObject;
WHILE t#NIL DO
d:=t;
FreeObject(NIL,d);
t:=t^.nextObject;
END;
CutRememberStructure(rememberDisplay,display,TRUE);
END;
display:=NIL;
END FreeDisplay;
VAR obj : ObjectHandlePtr;
mem : ADDRESS;
rem : NewRememberPtr;
ras : RasterPtr;
BEGIN
sinus:=ADR(SinusTable);
CLOSE
rem:=rememberRaster;
WHILE rem#NIL DO
ras:=GetAddress(rem);
CloseTmpRas(ras);
rem:=rem^.next;
END;
NewFreeRemember(rememberRaster,TRUE);
rem:=rememberObject;
WHILE rem#NIL DO
obj:=GetAddress(rem);
IF obj#NIL THEN
IF obj^.rememberData#NIL THEN
FreeRemember(ADR(obj^.rememberData),TRUE);
END;
END;
rem:=rem^.next;
END;
NewFreeRemember(rememberObject,TRUE);
NewFreeRemember(rememberDisplay,TRUE);
END Simple3D.